package lumis.portal.channel.acl;

import lumis.portal.*;
import lumis.portal.authentication.SessionConfig;
import lumis.portal.channel.*;
import lumis.portal.dao.*;
import lumis.portal.manager.*;
import lumis.util.*;
import lumis.util.security.acl.*;

import java.util.HashMap;

/**
 * Manager for Channel's Acl operations
 *
 * @version $Revision: 7037 $ $Date: 2007-05-25 22:53:02 -0300 (Fri, 25 May 2007) $
 * @since 4.0.0
 */
public class ChannelAclManager extends AclManager implements IChannelAclManager
{
	public String add(SessionConfig sessionConfig, ChannelConfig channelConfig, ITransaction transaction) throws ManagerException, PortalException
	{
		// check permission
		if (!checkPermission(sessionConfig, channelConfig.getParentId(), ChannelPermissions.MANAGE_CHANNEL, transaction))
			throw new AccessDeniedException();

		// create new acl
		AccessControlList parentAcl = null;
		HashMap<Integer, Integer> permissionsMap = null; //TODO: This would be set to an empty HashMap and super.add would accepty empty maps instead of null
		
		if (channelConfig.getParentId() != null)
		{
			parentAcl = getAclInternal(sessionConfig, channelConfig.getParentId(), transaction);
		}
		else
		{
			parentAcl = ManagerFactory.getPortalAclManager().get(sessionConfig, transaction);
			permissionsMap = ChannelPermissions.getInheritPermissionsMap();
		}

		String aclId = super.add(parentAcl, permissionsMap, ChannelPermissions.getImplies(), transaction);
		channelConfig.setAccessControlListId(aclId);
		
		return aclId;
	}

	public AccessControlList get(SessionConfig sessionConfig, String channelId, ITransaction transaction) throws ManagerException, PortalException
	{
		return getAclInternal(sessionConfig, channelId, transaction);
	}

	public void update(SessionConfig sessionConfig, String channelId, AccessControlList acl, ITransaction transaction) throws ManagerException, PortalException
	{
		// check permission
		if (!checkPermission(sessionConfig, channelId, ChannelPermissions.MANAGE_CHANNEL_SECURITY, transaction))
			throw new AccessDeniedException();

		ChannelConfig channelConfig = ManagerFactory.getChannelManager().get(sessionConfig, channelId, transaction);
		String channelAcl = channelConfig.getAccessControlListId();
		if (!channelAcl.equals(acl.getId()))
			throw new PortalException("STR_INVALID_ACCESS_CONTROL_LIST");

		// force implied permissions
		acl.setImpliedPermissions(ChannelPermissions.getImplies());

		super.update(acl, transaction);
	}

	protected AccessControlList getAclInternal(SessionConfig sessionConfig, String channelId, ITransaction transaction) throws ManagerException, PortalException
	{
		AccessControlList acl = null;
		
		if(channelId == null)
		{
			acl = ManagerFactory.getPortalAclManager().get(sessionConfig, transaction);
		}
		else
		{
			ChannelConfig channelConfig = ManagerFactory.getChannelManager().get(sessionConfig, channelId, transaction);
			
			acl = aclCache.get(channelConfig.getAccessControlListId());
			if (acl == null)
			{
				acl = DaoFactory.getAccessControlDao().get(channelConfig.getAccessControlListId(), transaction);
	
				if (acl.isInheriting())
				{
					AccessControlList parentAcl = getAclInternal(sessionConfig, channelConfig.getParentId(), transaction);
					if (channelConfig.getParentId() != null)
						acl.inherit(parentAcl);
					else
						acl.inherit(parentAcl, ChannelPermissions.getInheritPermissionsMap());
				}
	
				acl.setImpliedPermissions(ChannelPermissions.getImplies());
	
				aclCache.put(acl.getId(), acl);
			}
		}

		return acl;
	}

	protected int getRequiredPermissions() throws PortalException
	{
		return ChannelPermissions.getRequiredPermissions();
	}
	
	public void checkRequiredPermissions(AccessControlList acl) throws PortalException
	{
		super.checkRequiredPermissionsInternal(acl);
	}
}
